package com.ckzp.jfinal.base;

import com.ckzp.core.ConfigUtil;
import com.ckzp.core.json.JsonUtil;
import com.ckzp.core.util.DateUtil;
import com.ckzp.core.util.ParamUtil;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Page;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

/**
 * Created by 51594 on 2022/8/1.
 */
public class PageSearch {

    /**
     * debug
     */
    public static boolean DEBUG = ConfigUtil.DEBUG();

    /**
     * page id ,page number
     */
    protected int pagenum = 1;

    /**
     * page size,limit
     */
    protected int pagesize = 10;

    /**
     * select sql
     */
    protected String sql_select = "select * ";

    /**
     * order by
     */
    protected String orderby = "";

    /**
     * sql
     */
    protected StringBuffer sql_base = new StringBuffer();

    /**
     * value list
     */
    protected List select_value = new ArrayList();

    public static PageSearch n() {
        return new PageSearch();
    }

    /**
     * set page number
     * default:1
     *
     * @param pagenum
     * @return
     */
    public PageSearch setNum(int pagenum) {
        this.pagenum = pagenum;
        return this;
    }

    /**
     * set page size
     * default 10
     *
     * @param pagesize
     * @return
     */
    public PageSearch setSize(int pagesize) {
        this.pagesize = pagesize;
        return this;
    }

    /**
     * set sql ,must
     *
     * @param sql_base
     * @return
     */
    public PageSearch setSql(String sql_base) {
        this.sql_base.append(sql_base);
        return this;
    }


    /**
     * set sql ,must
     *
     * @param tables
     * @return
     */
    public PageSearch setTable(String tables) {
        this.sql_base.append(" from " + tables);
        return this;
    }

    /**
     * set select area
     * default:select *
     *
     * @param sql_select
     * @return
     */
    public PageSearch setSelect(String sql_select) {
        this.sql_select = sql_select;
        return this;
    }

    /**
     * add search column
     *
     * @param column
     * @param value
     * @return
     */
    public PageSearch search(String column, String value) {
        if (value == null || String.valueOf(value).length() == 0) return this;
        if (sql_base.indexOf("where") == -1) {
            sql_base.append(" where " + column + "=?");
        } else {
            sql_base.append(" and " + column + "=?");
        }
        select_value.add(value);
        return this;
    }

    /**
     * add search column
     *
     * @param column
     * @param value
     * @return
     */
    public PageSearch search(String column, int value) {
        if (sql_base.indexOf("where") == -1) {
            sql_base.append(" where " + column + "=?");
        } else {
            sql_base.append(" and " + column + "=?");
        }
        select_value.add(value);
        return this;
    }

    /**
     * add search column
     *
     * @param column
     * @param value
     * @return
     */
    public PageSearch search(String column, String logic, int value) {
        if (sql_base.indexOf("where") == -1) {
            sql_base.append(" where " + column + " " + logic + " ?");
        } else {
            sql_base.append(" and " + column + " " + logic + " ?");
        }
        select_value.add(value);
        return this;
    }

    /**
     * add search column
     *
     * @param column
     * @param value
     * @return
     */
    public PageSearch search(String column, String logic, Object value) {
        if (sql_base.indexOf("where") == -1) {
            if ("in".equals(logic)) {
                sql_base.append(" where  find_in_set(" + column + ",?)");
            } else {
                sql_base.append(" where " + column + " " + logic + " ?");
            }
        } else {
            if ("in".equals(logic)) {
                sql_base.append(" and  find_in_set(" + column + ",?)");
            } else {
                sql_base.append(" and " + column + " " + logic + " ?");
            }
        }
        select_value.add(value);
        return this;
    }

    /**
     * init all search
     * begin with s[
     *
     * @param request
     * @return
     */
    public PageSearch init(HttpServletRequest request) {
        this.setNum(ParamUtil.getInt(request, "page", 1));
        this.setSize(ParamUtil.getInt(request, "limit", 10));
        this.orderby(ParamUtil.getString(request, "orderby", ""));
        this.initSearch(request);
        return this;
    }

    /**
     * init all search
     * begin with s[
     *
     * @param request
     * @return
     */
    public PageSearch init(HttpServletRequest request, String tablename) {
        this.setTable(tablename);
        this.setNum(ParamUtil.getInt(request, "page", 1));
        this.setSize(ParamUtil.getInt(request, "limit", 10));
        this.orderby(ParamUtil.getString(request, "orderby", ""));
        this.initSearch(request);
        return this;
    }

    /**
     * init all search
     * begin with s[
     *
     * @param request
     * @return
     */
    public PageSearch initSearch(HttpServletRequest request) {
        Enumeration el = request.getParameterNames();
        while (el.hasMoreElements()) {
            String names = el.nextElement().toString();
            if (names.startsWith("s[") && names.endsWith("]")) {
                String column = names.substring(2, names.length() - 1);
                this.search(column, ParamUtil.getString(request, names));
            } else if (names.startsWith("like[") && names.endsWith("]")) {
                String column = names.substring(5, names.length() - 1);
                this.like(column, ParamUtil.getString(request, names));
            }
        }
        return this;
    }

    /**
     * add search column
     *
     * @param column
     * @param logic
     * @param types
     * @param value
     * @return
     */
    public PageSearch search(String column, String logic, String types, String value) {
        if (value == null || String.valueOf(value).length() == 0) return this;
        if (sql_base.indexOf("where") == -1) {
            sql_base.append(" where " + column + logic + "?");
        } else {
            sql_base.append(" and " + column + logic + "?");
        }
        if ("int".equals(types)) {
            select_value.add(Integer.valueOf(value));
        } else if ("date".equals(types)) {
            select_value.add(DateUtil.getDate(value));
        } else {
            select_value.add(value);
        }
        return this;
    }

    /**
     * add search column
     *
     * @param addsql
     * @return
     */
    public PageSearch add(String addsql) {
        sql_base.append(" " + addsql);
        return this;
    }


    /**
     * add search value
     *
     * @param value
     * @return
     */
    public PageSearch addValue(Object value) {
        select_value.add(value);
        return this;
    }

    /**
     * add search column
     *
     * @param column
     * @param value
     * @return
     */
    public PageSearch searchInt(String column, String value) {
        if (value == null || String.valueOf(value).length() == 0) return this;
        if (sql_base.indexOf("where") == -1) {
            sql_base.append(" where " + column + "=?");
        } else {
            sql_base.append(" and " + column + "=?");
        }
        select_value.add(Integer.valueOf(value));
        return this;
    }


    /**
     * add search column
     *
     * @param column
     * @param value
     * @return
     */
    public PageSearch searchInt(String column, Integer value) {
        if (value == null || String.valueOf(value).length() == 0) return this;
        if (sql_base.indexOf("where") == -1) {
            sql_base.append(" where " + column + "=?");
        } else {
            sql_base.append(" and " + column + "=?");
        }
        select_value.add(Integer.valueOf(value));
        return this;
    }

    /**
     * add search column
     *
     * @param column
     * @param value
     * @return
     */
    public PageSearch searchDate(String column, String value) {
        if (value == null || String.valueOf(value).length() == 0) return this;
        if (sql_base.indexOf("where") == -1) {
            sql_base.append(" where " + column + "=?");
        } else {
            sql_base.append(" and " + column + "=?");
        }
        select_value.add(DateUtil.getDate(value));
        return this;
    }

    /**
     * add like search column
     *
     * @param column
     * @param value
     * @return
     */
    public PageSearch like(String column, Object value) {
        if (value == null || String.valueOf(value).length() == 0) return this;
        if (sql_base.indexOf("where") == -1) {
            sql_base.append(" where  " + column + " like ?");
        } else {
            sql_base.append(" and " + column + " like ?");
        }
        select_value.add("%" + value + "%");
        return this;
    }


    /**
     * add like search column
     *
     * @param likes
     * @return
     */
    public PageSearch orLikes(List<String[]> likes) {
        if (likes == null || likes.size() == 0) return this;
        if (sql_base.indexOf("where") == -1) {
            sql_base.append(" where  ");
        } else {
            sql_base.append(" and ");
        }
        sql_base.append("(");
        for (int k = 0; k < likes.size(); k++) {
            String[] kv = likes.get(k);
            String column = kv[0];
            String value = kv[1];
            if (k > 0) sql_base.append(" or ");
            sql_base.append(column + " like ? ");
            select_value.add("%" + value + "%");
        }
        sql_base.append(")");
        return this;
    }

    /**
     * add like search column
     *
     * @param column
     * @param value
     * @return
     */
    public PageSearch likeLeft(String column, Object value) {
        if (value == null || String.valueOf(value).length() == 0) return this;
        if (sql_base.indexOf("where") == -1) {
            sql_base.append(" where  " + column + " like ?");
        } else {
            sql_base.append(" and " + column + " like ?");
        }
        select_value.add("%" + value + "");
        return this;
    }

    /**
     * add like search column
     *
     * @param column
     * @param value
     * @return
     */
    public PageSearch likeRight(String column, Object value) {
        if (value == null || String.valueOf(value).length() == 0) return this;
        if (sql_base.indexOf("where") == -1) {
            sql_base.append(" where  " + column + " like ?");
        } else {
            sql_base.append(" and " + column + " like ?");
        }
        select_value.add("" + value + "%");
        return this;
    }

    /**
     * add orderby
     *
     * @param orderby
     * @return
     */
    public PageSearch orderby(String orderby) {
        this.orderby = orderby;
        return this;
    }

    /**
     * add orderby
     *
     * @param request
     * @return
     */
    public PageSearch orderby(HttpServletRequest request) {
        this.orderby = ParamUtil.getString(request, "orderby");
        return this;
    }

    /**
     * add orderby
     *
     * @param request
     * @return
     */
    public PageSearch orderby(HttpServletRequest request, String orderby) {
        this.orderby = ParamUtil.getString(request, "orderby", orderby);
        return this;
    }

    /**
     * get sql base
     *
     * @return
     */
    public String getSql() {
        return sql_base.toString();
    }


    /**
     * get value
     *
     * @return
     */
    public String getValue() {
        return JsonUtil.toJsonString(select_value);
    }

    /**
     * do search result
     *
     * @param dao
     * @return
     */
    public Page paginate(Model dao) {
        if (orderby != null && orderby.length() > 0) {
            sql_base.append(" order by " + orderby);
        }
        if (ConfigUtil.DEBUG()) {
            System.out.println("-----------------------search---------------------------------------------");
            System.out.println("pagenum         :" + pagenum);
            System.out.println("pagesize        :" + pagesize);
            System.out.println("select          :" + sql_select);
            System.out.println("sql             :" + sql_base.toString());
            System.out.println("value           :" + JsonUtil.toJsonString(select_value));
            System.out.println("-----------------------search end---------------------------------------------");
        }
        return dao.paginate(pagenum, pagesize, sql_select, sql_base.toString(), select_value.toArray());
    }
}
